﻿@using AntDesign.Core.JsInterop.Modules.Components
@inherits AntDesignTestBase
@code {
    public Select_Tags_Tests()
    {
        JSInterop.Setup<AntDesign.JsInterop.DomRect>(JSInteropConstants.GetBoundingClientRect, _ => true)
            .SetResult(new AntDesign.JsInterop.DomRect());         			
        JSInterop.Setup<HtmlElement>(JSInteropConstants.GetDomInfo, _ => true)
            .SetResult(new HtmlElement());

		JSInterop.SetupVoid(JSInteropConstants.AddPreventKeys, _ => true);		
		JSInterop.SetupVoid(JSInteropConstants.AddElementTo, _ => true);		
#if !NET6_0_OR_GREATER
#pragma warning disable CS0618 // Type or member is obsolete
            JSInterop.SetupVoid(JSInteropConstants.Focus, _ => true).SetVoidResult(); ;
#pragma warning restore CS0618 // Type or member is obsolete
#endif
    }

    [Fact]
    public async Task Single_tag_creation() //issue #1645
    {
        //Arrange
        JSInterop.Setup<OverlayPosition>(JSInteropConstants.OverlayComponentHelper.AddOverlayToContainer, _ => true)
            .SetResult(new OverlayPosition() { Top = 0, Left = 0, ZIndex = 5000, Placement = Placement.BottomLeft });               

        var cut = Render<AntDesign.Select<string, string>>(
        @<AntDesign.Select Mode="tags"
			TItemValue="string"
			TItem="string"
            SearchDebounceMilliseconds="0"
			EnableSearch>
			<SelectOptions>						
				<SelectOption TItemValue="string" TItem="string" Value="@("1")" Label="1" />			
			</SelectOptions>
        </AntDesign.Select>
        );        

        var input = cut.Find("input.ant-select-selection-search-input");        
        //Act
        await cut.InvokeAsync(() => input.Input("A"));
        await cut.InvokeAsync(() => cut.WaitForState(() => cut.Instance.ActiveOption is not null));
        input.KeyUp("ENTER");
        input.Input("B");
        await cut.InvokeAsync(() => cut.WaitForState(() => cut.Instance.ActiveOption.Value == "B"));
        input.KeyUp("ENTER");
        input.Input("C");		
        await cut.InvokeAsync(() => cut.WaitForState(() => cut.Instance.ActiveOption.Value == "C"));
        input.KeyUp("ENTER");        
        //Assert
        var addedTags = cut.FindAll("span.ant-select-selection-item-content")
            .Where(d => d.TextContent.Trim() == "B");
        addedTags.Should().HaveCount(1);
        cut.WaitForAssertion(() => cut.Instance.SelectedOptionItems.Should().HaveCount(3));        
    }

    [Fact]
    public void Tag_MaxTagCount_sets_tags_in_proper_order() //issue #1746
    {
        //Arrange

		IEnumerable<string> values = new string[] { "1", "2", "3", "4", "5", "6" };
        var cut = Render<AntDesign.Select<string, string>>(
			@<AntDesign.Select Mode="tags"        		
				TItemValue="string"
				TItem="string"						
				MaxTagCount="2"
				>
				<SelectOptions>						
					@foreach(var value in values)
					{
						<SelectOption TItemValue="string" TItem="string" Value="@value" Label="@value" />									
					}
				</SelectOptions>
            </AntDesign.Select>
    );
        //Act

        //TOOD: When using @bind-Values, bUnit does not render the selected items. This 
        //		Requires investigation - more likely scenario is that Select components
        //		should be refactored.
        cut.SetParametersAndRender(parameters => parameters.Add(p => p.Values, values));   		
        //Assert
        var items = cut.Find("div.ant-select-selection-overflow").Children;
        var tags = items.Where(i => i.ClassList.Count() == 1);
        var rest = items.Filter(".ant-select-selection-overflow-item-rest");
        var input = items.Filter(".ant-select-selection-overflow-item-suffix");

        items.Should().HaveCount(4);
        tags.Should().HaveCount(2);
        rest.Should().HaveCount(1);
        rest.ElementAt(0).GetAttribute("style").Should().Contain("order: 5");
        input.Should().HaveCount(1);
        input.ElementAt(0).GetAttribute("style").Should().Contain("order: 6");
    }

    [Fact]
    public async Task ItShouldAddTags_WhenDatasourceIsEmpty()
    {
        //Arrange
        JSInterop.Setup<OverlayPosition>(JSInteropConstants.OverlayComponentHelper.AddOverlayToContainer, _ => true)
            .SetResult(new OverlayPosition() { Top = 0, Left = 0, ZIndex = 5000, Placement = Placement.BottomLeft });

        var datasource = new List<string>();

        var systemUnderTest = Render<Select<string, string>>(
            @<AntDesign.Select Mode="tags" TItemValue="string" TItem="string" DataSource="datasource" EnableSearch SearchDebounceMilliseconds="0"/>
        );

        var input = systemUnderTest.Find("input.ant-select-selection-search-input");

        await systemUnderTest.InvokeAsync(() => input.Input("Tag1"));
        await systemUnderTest.InvokeAsync(() => systemUnderTest.WaitForState(() => systemUnderTest.Instance.ActiveOption is not null));
        input.KeyUp("ENTER");

        input.Input("Tag2");
        await systemUnderTest.InvokeAsync(() => systemUnderTest.WaitForState(() => systemUnderTest.Instance.ActiveOption.Value.Equals("Tag2")));
        input.KeyUp("ENTER");
        systemUnderTest.WaitForAssertion(() => systemUnderTest.FindAll("span.ant-select-selection-item-content")
            .Select(x => x.TextContent.Trim())
            .Should()
            .BeEquivalentTo(new[] { "Tag1", "Tag2" }));
    }
}
}